#include "communication.h"
#include "m1190.h"
#include "Dload.h"
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include "cutils/properties.h"
#include "compatible.h"
//#include "atchannel.h"

static void* power_on_thread(void* arg)
{
	set_m7281_power(1);
	return NULL;
}

static void startPowerOnThread(pthread_t* tid, const char* device) 
{
	ALOGD("%s", __func__);                                                     
	pthread_attr_t attr;                                                      
	pthread_attr_init (&attr);                                                
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);              
	pthread_create(tid, &attr, power_on_thread, (void *)device);       
}

static int write_line(int fd, const char *s)
{
    size_t cur = 0;
    size_t len = strlen(s);
    ssize_t written;

    if (fd < 0) {
        return -1;
    }

    ALOGD("AT> %s\n", s);

    /* the main string */
    while (cur < len) {
        do {
            written = write (fd, s + cur, len - cur);
        } while (written < 0);

        if (written < 0) {
            return -1;
        }

        cur += written;
    }

    /* the \r  */

    do {
        written = write (fd, "\r" , 1);
    } while ((written < 0) || (written == 0));

    if (written < 0) {
        return -1;
    }

    return 0;
}

static int enterDownloadMode(const char *device)
{
	int fd = -1;
    int ret = -1;
    const char * cmd = "AT+SPREF=\"AUTODLOADER\"";
 
    fd = open(device,O_RDWR);        
    ALOGE("open : %s ",(fd >= 0) ? "success" : "failed");
	if(fd < 0)
	{
	    return -1;	
	}

    ret = write_line(fd , cmd);
    ALOGE("write : %s ",(ret >= 0) ? "success" : "failed");
	if(ret < 0)
	{
	    return -2;	
	}

    if(fd > 0)
	{
	    close(fd);
	}
	return 1;
}

BOOL M7281_DownLoad(BIN_PACKET_HEADER_T* bph,FILE_T* pArrFile, const char* device)
{
	int i = 0;
	BOOL bRet = 1;
	

	for (i = 0; i < bph->nFileCount; i++)
	{
		FILE_T* pFile = pArrFile+i;
		ALOGD("Downloading %s mCheckFlag:%d", pFile->szFileID, pFile->nCheckFlag);	
		if (pFile->nCheckFlag)
		{
			if (strcasecmp(pFile->szFileID, "fdl") == 0)
			{
				pthread_t power_t;
				startPowerOnThread(&power_t, device);
				sleep(10);
				int ret = 0;
				while((ret = open_com("/dev/ttyUSB0")) == 0) {
				    ALOGE("open serial failed \n");
				    usleep(500);
				}

				usleep(5000);
				bRet = mDownloadCallback.onDownloadFDL(0x40000000, (long)pFile);
				if(bRet == 0) {
					ALOGE("M7281_DownLoad close com");
					close_com();
					return FALSE;
				}
			}
			else if (strcasecmp(pFile->szFileID, "fdl2") == 0)
			{
			        bRet = mDownloadCallback.onDownloadFDL2(0x0, (long)pFile);
			}
			else if (strcasecmp(pFile->szFileID, "nv") == 0)
			{
			        bRet = mDownloadCallback.onDownloadNV(0x90000001, (long)pFile);
			}			
			else if (strcasecmp(pFile->szFileID, "BootLoader") == 0)
			{
				bRet = mDownloadCallback.onDownload(0x80000000, (long)pFile);
			}
			else if (strcasecmp(pFile->szFileID, "KernelImg") == 0)
			{
				bRet = DownloadKernel(0x80000003, (long)pFile);
			}
			else if (strcasecmp(pFile->szFileID, "DSPCode") == 0)
			{
				bRet = mDownloadCallback.onDownload(0x90000005, (long)pFile);
			}
			else if (strcasecmp(pFile->szFileID, "ControlData") == 0)
			{
				bRet = mDownloadCallback.onDownload(0x90000011, (long)pFile);
			}
			else if (strcasecmp(pFile->szFileID, "FLASH") == 0)
			{
	                        bRet = FormatFlash(0x90000003, (long)pFile);
			}
			else if (strcasecmp(pFile->szFileID, "RESTAUTODOWNFLAG") == 0)
			{
				bRet = EraseFlash(0x90000010, (long)pFile);
				ALOGE("M7281_DownLoad RESTAUTODOWNFLAG--:%s", bRet ? "SUCCESS" : "FAILED");
			}			
		}  	 

		if (bRet == 0)
		{		
			ALOGE("M7281_DownLoad close com");	
			close_com();
			break;
		}		
	}

	return bRet;
}

int m7281_download(int argc, char** argv)
{
	int ret=0;
	BIN_PACKET_HEADER_T bph;
	FILE_T* pArrFile;
	
	write_status_file(STATE_FILE_PATH, STATE_DOWNLOADING_STR, "");
	set_m7281_power(0);
    ret = OpenPac("/mnt/extsd/m7281.pac");
	if(ret == 0) 
	{
		ret = OpenPac("/mnt/sdcard/m7281.pac");
		if(ret == 0) 
		{
			ALOGE("open pac failed \n");
			write_status_file(STATE_FILE_PATH, STATE_FAILED_STR, "Open pac failed");
			return 0;
		}
    } 

    ret = mDownloadCallback.onUnpacket("/sdcard/pac", &bph, &pArrFile);;
	if(ret == 0)
	{
	    ALOGE("Unpacket pac failed \n");
		write_status_file(STATE_FILE_PATH, STATE_FAILED_STR, "Unpacket pac failed");
	    return 0;
    }
	else
	{
        ALOGE("Unpacket pac success \n");
	}
	
	enterDownloadMode(argv[1]);

    ret = M7281_DownLoad(&bph, pArrFile, argv[0]);
    if(ret == 0)
    {
        ALOGE("download failed \n");
		write_status_file(STATE_FILE_PATH, STATE_FAILED_STR, "download failed");
		return 0;
    }
	write_status_file(STATE_FILE_PATH, STATE_SUCCESS_STR, "");
	
	return 0;	
}



